<?php

namespace EasyVote\EasyVoteBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;


/**
 * This class represents important information on an election.
 *
 * @ORM\Entity()
 */
class Election
{
    /**
     * The id of the election
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * If true, the profiles in this election are candidates running for office.
     * @ORM\Column(name="isCandidateElection", type="boolean")
     */
    private $isCandidateElection;

    /**
     * If true, then write-in candidates are allowed.
     * @ORM\Column(name="writeInsAllowed", type="boolean")
     */
    private $writeInsAllowed;

    /**
     * Stores the start datetime after which options can be added to the election.
     * @ORM\Column(name="optionSubmissionStartDate", type="datetime")
     */
    private $optionSubmissionStartDate;

    /**
     * Stores the end datetime before which options can be added to the election.
     * @ORM\Column(name="optionSubmissionEndDate", type="datetime")
     */
    private $optionSubmissionEndDate;

    /**
     * Stores the start datetime after which options can be voted on.
     * @ORM\Column(name="votingStartDate", type="datetime")
     */
    private $votingStartDate;

    /**
     * Stores the end datetime before which options can be voted on.
     * @ORM\Column(name="votingEndDate", type="datetime")
     */
    private $votingEndDate;

    /**
     * Stores the election reminders. 
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="ElectionReminder")
     * @ORM\JoinTable(name="elections_electionreminders",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="electionreminder_id", referencedColumnName="id")}
     *      )
     */
    private $reminders;

    /**
     * Stores the affiliations that can vote. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Affiliation")
     * @ORM\JoinTable(name="elections_affiliations",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="affiliation_id", referencedColumnName="id")}
     *      )
     */
    private $affiliations;

    /**
     * Stores the scoped affiliations that can vote. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="ScopedAffiliation")
     * @ORM\JoinTable(name="elections_scopedaffiliations",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="scopedaffiliation_id", referencedColumnName="id")}
     *      )
     */
    private $scopedAffiliations;

    /**
     * Stores the votes associated with the election.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Vote")
     * @ORM\JoinTable(name="elections_votes",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="vote_id", referencedColumnName="id")}
     *      )
     */
    private $votes;

    /**
     * Stores the degrees that people can vote with. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Degree")
     * @ORM\JoinTable(name="elections_degrees",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="degree_id", referencedColumnName="id")}
     *      )
     */
    private $degrees;

    /**
     * Stores the departments that people can vote with. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Department")
     * @ORM\JoinTable(name="elections_departments",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="department_id", referencedColumnName="id")}
     *      )
     */
    private $departments;

    /**
     * Stores the jobs that people can vote with. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Job")
     * @ORM\JoinTable(name="elections_jobs",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="job_id", referencedColumnName="id")}
     *      )
     */
    private $jobs;

    /**
     * Stores the classifications that people can vote with. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Classification")
     * @ORM\JoinTable(name="elections_classifications",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="classification_id", referencedColumnName="id")}
     *      )
     */
    private $classifications;

    /**
     * Stores the roles that people can vote with. Currently not being used.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Role")
     * @ORM\JoinTable(name="elections_roles",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="role_id", referencedColumnName="id")}
     *      )
     */
    private $roleObjects;

    /**
     * Stores the approved profiles of candidates or other topics in the election
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Profile")
     * @ORM\JoinTable(name="elections_profiles",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="profile_id", referencedColumnName="id")}
     *      )
     */
    private $profiles;

    /**
     * Stores the write-in profiles of the election.
     * @var ArrayCollection
     * @ORM\ManyToMany(targetEntity="Profile")
     * @ORM\JoinTable(name="elections_writeinprofiles",
     *      joinColumns={@ORM\JoinColumn(name="election_id", referencedColumnName="id")},
     *      inverseJoinColumns={@ORM\JoinColumn(name="profile_id", referencedColumnName="id")}
     *      )
     */
    private $writeInProfiles;

    /**
     * Stores the url to an image.
     * @var string
     * @ORM\Column(name="imageURL", type="string")
     */
    private $imageURL;

    /**
     * Stores alternate text
     * @var string
     * @ORM\Column(name="altText", type="string")
     */
    private $altText;

    /**
     * A short executive summary for the election.
     * @var string
     * @ORM\Column(name="summary", type="text")
     */
    private $summary;

    /**
     * A larger description for the election.
     * @var string
     * @ORM\Column(name="ftext", type="text")
     */
    private $ftext;

    /**
     * Stores the title of the election.
     * @var string
     * @ORM\Column(name="title", type="string")
     */
    private $title;

    /**
     * Default constructor.
     */
    public function __construct()
    {
        $this->classifications = new ArrayCollection;
        $this->jobs = new ArrayCollection;
        $this->departments = new ArrayCollection;
        $this->degrees = new ArrayCollection;
        $this->roleObjects = new ArrayCollection;
        $this->affiliations = new ArrayCollection;
        $this->scopedAffiliations = new ArrayCollection;
        $this->profiles = new ArrayCollection;
        $this->writeInProfiles = new ArrayCollection;
        $this->reminders = new ArrayCollection;
    }

    /**
     * Gets the option submission start date.
     * @return \DateTime the option submission start date
     */
    public function getOptionSubmissionStartDate()
    {
        return $this->optionSubmissionStartDate;
    }

    /**
     * Sets the option submission start date.
     * @param \DateTime $optionSubmissionStartDate the new start date.
     */
    public function setOptionSubmissionStartDate(\DateTime $optionSubmissionStartDate)
    {
        $this->optionSubmissionStartDate = $optionSubmissionStartDate;
    }

    /**
     * Gets the option submission end date.
     * @return \DateTime the option submission end date
     */
    public function getOptionSubmissionEndDate()
    {
        return $this->optionSubmissionEndDate;
    }

    /**
     * Sets the option submission end date.
     * @param \DateTime $optionSubmissionEndDate the new end date for adding stuff to the election.
     */
    public function setOptionSubmissionEndDate(\DateTime $optionSubmissionEndDate)
    {
        $this->optionSubmissionEndDate = $optionSubmissionEndDate;
    }

    /**
     * Gets the voting start date.
     * @return \DateTime the voting start date
     */
    public function getVotingStartDate()
    {
        return $this->votingStartDate;
    }

    /**
     * Sets the voting start date.
     * @param \DateTime $votingStartDate the voting start date
     */
    public function setVotingStartDate(\DateTime $votingStartDate)
    {
        $this->votingStartDate = $votingStartDate;
    }

    /**
     * Gets the voting end date.
     * @return \DateTime the voting end date
     */
    public function getVotingEndDate()
    {
        return $this->votingEndDate;
    }

    /**
     * Sets the voting end date.
     * @param \DateTime $votingEndDate the end date of voting.
     */
    public function setVotingEndDate(\DateTime $votingEndDate)
    {
        $this->votingEndDate = $votingEndDate;
    }

    /**
     * Get scoped affiliations
     *
     * @return ArrayCollection
     */
    public function getScopedAffiliations()
    {
        return $this->scopedAffiliations;
    }

    /**
     * Add Scoped affiliation
     *
     * @param ScopedAffiliation $scopedAffiliation
     */
    public function addScopedAffiliation(ScopedAffiliation $scopedAffiliation)
    {
        if (!$this->scopedAffiliations->contains($scopedAffiliation)) {
            $this->scopedAffiliations->add($scopedAffiliation);
        }
    }

    /**
     * Remove scoped affiliation
     *
     * @param ScopedAffiliation $scopedAffiliation
     * @return true if removal successful; otherwise false.
     */
    public function removeScopedAffiliation(ScopedAffiliation $scopedAffiliation)
    {
        return ($this->scopedAffiliations->removeElement($scopedAffiliation));
    }

    /**
     * Get reminders
     *
     * @return ArrayCollection
     */
    public function getReminders()
    {
        return $this->reminders;
    }

    /**
     * Add reminder
     * @param ElectionReminder $reminder
     */
    public function addReminder(ElectionReminder $reminder)
    {
        if (!$this->reminders->contains($reminder)) {
            $this->reminders->add($reminder);
        }
    }

    /**
     * Remove reminder
     *
     * @param ElectionReminder $reminder
     * @return true if removal successful; otherwise false.
     */
    public function removeReminder(ElectionReminder $reminder)
    {
        return ($this->reminders->removeElement($reminder));
    }

    /**
     * Get profiles
     *
     * @return ArrayCollection
     */
    public function getProfiles()
    {
        return $this->profiles;
    }

    /**
     * Add a profile to an election
     *
     * @param Profile $profile the profile to add
     */
    public function addProfile(Profile $profile)
    {
        if (!$this->profiles->contains($profile)) {
            $this->profiles->add($profile);
        }
    }

    /**
     * Remove a profile from an election
     *
     * @param Profile $profile the profile to remove
     * @return true if removal is successful
     */
    public function removeProfile(Profile $profile)
    {
        return ($this->profiles->removeElement($profile));
    }

    /**
     * Get votes
     *
     * @return ArrayCollection
     */
    public function getVotes()
    {
        return $this->votes;
    }

    /**
     * Add a vote to an election
     *
     * @param Vote $vote the vote to add
     */
    public function addVote(Vote $vote)
    {
        if (!$this->votes->contains($vote)) {
            $this->votes->add($vote);
        }
    }

    /**
     * Remove a vote from an election
     *
     * @param Vote $vote
     * @return true if successful
     */
    public function removeVote(Vote $vote)
    {
        return $this->votes->removeElement($vote);
    }

    /**
     * Get profiles
     *
     * @return ArrayCollection
     */
    public function getWriteInProfiles()
    {
        return $this->writeInProfiles;
    }

    /**
     * Add a profile to an election
     *
     * @param Profile $profile the profile
     * @return boolean indicating success or failure
     */
    public function addWriteInProfile(Profile $profile)
    {
        if (!$this->writeInProfiles->contains($profile)) {
            $this->writeInProfiles->add($profile);
        }
    }

    /**
     * Remove a profile from an election
     *
     * @param Profile $profile
     * @return boolean indicating success or failure
     */
    public function removeWriteInProfile(Profile $profile)
    {
        return ($this->writeInProfiles->removeElement($profile));
    }

    /**
     * Get affiliations
     *
     * @return ArrayCollection
     */
    public function getAffiliations()
    {
        return $this->affiliations;
    }

    /**
     * Add affiliation
     *
     * @param Affiliation $affiliation
     * @return User
     */
    public function addAffiliation(Affiliation $affiliation)
    {
        if (!$this->affiliations->contains($affiliation)) {
            $this->affiliations->add($affiliation);
        }
    }

    /**
     * Remove affiliation
     *
     * @param Affiliation $affiliation
     * @return boolean indicating success or failure
     */
    public function removeAffiliation(Affiliation $affiliation)
    {
        return ($this->affiliations->removeElement($affiliation));
    }

    /**
     * Get degrees
     *
     * @return ArrayCollection
     */
    public function getDegrees()
    {
        return $this->degrees;
    }

    /**
     * Add degree
     *
     * @param Degree $degree
     */
    public function addDegree(Degree $degree)
    {
        if (!$this->degrees->contains($degree)) {
            $this->degrees->add($degree);
        }
    }

    /**
     * Remove degree
     *
     * @param Degree $degree
     * @return boolean indicating success or failure
     */
    public function removeDegree(Degree $degree)
    {
        return $this->degrees->removeElement($degree);
    }

    /**
     * Get jobs
     *
     * @return ArrayCollection
     */
    public function getJobs()
    {
        return $this->jobs;
    }

    /**
     * Add job
     *
     * @param Job $job
     * @return User
     */
    public function addJob(Job $job)
    {
        if (!$this->jobs->contains($job)) {
            $this->jobs->add($job);
        }
    }

    /**
     * Remove job
     *
     * @param Job $job
     */
    public function removeJob(Job $job)
    {
        $this->jobs->removeElement($job);
    }

    /**
     * Get jobs
     *
     * @return ArrayCollection
     */
    public function getClassifications()
    {
        return $this->classifications;
    }

    /**
     * Add classification
     *
     * @param Classification $classification
     * @return Election
     */
    public function addClassification(Classification $classification)
    {
        if (!$this->classifications->contains($classification)) {
            $this->classifications->add($classification);
        }
    }

    /**
     * Remove classification
     *
     * @param Classification $classification
     * @return true if removal is successful
     */
    public function removeClassification(Classification $classification)
    {
        return ($this->classifications->removeElement($classification));
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set the text of the election description
     * @param string $ftext the text of the description
     */
    public function setText($ftext)
    {
        $this->ftext = $ftext;
    }

    /**
     * Get the text of the election description
     * @return string the text
     */
    public function getText()
    {
        return $this->ftext;
    }

    /**
     * Gets the summary text
     * @return string the summary text
     */
    public function getSummary()
    {
        return $this->summary;
    }

    /**
     * Set the election summary text
     * @param string $summary the new summary text
     */
    public function setSummary($summary)
    {
        $this->summary = $summary;
    }

    /**
     * Gets the title of the election
     * @return string
     */
    public function getTitle()
    {
        return $this->title;
    }

    /**
     * Sets the title of the election
     * @param string $title the title of the election
     */
    public function setTitle($title)
    {
        $this->title = $title;
    }

    /**
     * Gets the departments that people must be affiliated with in order to vote.
     * Currently not being used.
     * @return ArrayCollection the departments required to vote.
     */
    public function getDepartments()
    {
        return $this->departments;
    }

    /**
     * Sets the departments that can vote in the election.
     * Currently not being used.
     * @param ArrayCollection $departments The departments that can vote
     */
    public function setDepartments($departments)
    {
        $this->departments = $departments;
    }

    /**
     * Gets whether or not write ins are allowed.
     * @return mixed
     */
    public function getWriteInsAllowed()
    {
        return $this->writeInsAllowed;
    }

    /*
     * Sets whether or not write ins are allowed.
     * @param writeInsAllowed
     */
    public function setWriteInsAllowed($writeInsAllowed)
    {
        $this->writeInsAllowed = $writeInsAllowed;
    }

    /*
     * Get whether or not this is a candidate election
     */
    public function getIsCandidateElection()
    {
        return $this->isCandidateElection;
    }

    /*
     * Set whether or not this is a candidate election
     * @param isCandidateElection
     */
    public function setIsCandidateElection($isCandidateElection)
    {
        $this->isCandidateElection = $isCandidateElection;
    }

    /**
     * Gets the URL of the profile picture
     * @return string
     */
    public function getImageURL()
    {
        return $this->imageURL;
    }

    /*
     * Get imageURL
     * @return string
     */
    public function setImageURL($imageURL)
    {
        $this->imageURL = $imageURL;
    }

    /*
     * Set alternate text
     * @param altText
     * @return Profile
     */
    public function getAltText()
    {
        return $this->altText;
    }

    /*
     * Get alternate text
     * @return string
     */
    public function setAltText($altText)
    {
        $this->altText = $altText;
    }
}

?>
